/*
 * FSWUniCEUB - 2008
 * 
 * Este arquivo é de propriedade da Fábrica de Software do UniCEUB
 * 
 * Para mais informações entre em contato com a coordenação do
 * curso de Ciência da Computação da instituição.
 */

package br.uniceub.fsw.indicadores.bo;

import br.uniceub.fsw.arquitetura.persistencia.transacao.Transacao;
import br.uniceub.fsw.arquitetura.servico.exception.NegocioException;
import br.uniceub.fsw.indicadores.dao.PlanoMedicaoDAO;
import br.uniceub.fsw.indicadores.vo.PlanoMedicaoVO;
import java.util.Date;

/**
 * Business Object da entidade PlanoMedicao. Essa classe é responsável por todos as
 * funcionalidades de negócio relacionadas à entidade.
 * 
 @author Filipe Scafuto Vieira ra20463917
 */
public class PlanoMedicaoBO {

   PlanoMedicaoDAO planoMedicaoDAO = new PlanoMedicaoDAO();
    
   
   
    /**
     * Valida se o registro do plano de medição está pronto para inserção ou atualização.
     * 
     * @param planoMedicao plano de medição a ser verificado.
     * @throws br.uniceub.fsw.arquitetura.servico.exception.RegraNegocioException caso o plano de medição 
     * informado não possua condições de ser inserido ou atualizado no banco de dados.
     */
    public void validaPlanoMedicao(PlanoMedicaoVO planoMedicao, boolean eNovo) throws Exception, NegocioException {
        
        String mensagem = new String();
        
        if(!eNovo && planoMedicao.getIdPlanoMedicao() == null) {
            mensagem = mensagem.concat("ID do plano de medição não informado.<br />");
        }
        if(planoMedicao.getNoPlanoMedicao() == null || planoMedicao.getNoPlanoMedicao().equals("")) {
            mensagem = mensagem.concat("Nome do plano de medição obrigatório.<br />");
        }
        if(planoMedicao.getDsPlanoMedicao() == null || planoMedicao.getDsPlanoMedicao().equals("")) {
            mensagem = mensagem.concat("Descrição do plano de medição obrigatória.<br />");
        }
        if(planoMedicao.getDtValidade() == null) {
            mensagem = mensagem.concat("Data de validade do plano de medição obrigatória.<br />");
        }
        if(eNovo && planoMedicao.getNoPlanoMedicao() != null && !planoMedicao.getNoPlanoMedicao().isEmpty()) {
            try {
                validarVOUnico(planoMedicao);
            }
            catch(NegocioException e) {
                mensagem = mensagem.concat(e.getMessage());
            }
            catch(Exception e) {
                throw new Exception(e.getMessage());
            }
        }
        
        if(!mensagem.isEmpty())
            throw new NegocioException(mensagem);
    }

    /**
     * Valida se já existe um registro de plano de medição no Banco de Dados como verificação para inserção.
     * 
     * @param planoMedicao plano de medição a ser verificado.
     * @throws br.uniceub.fsw.arquitetura.servico.exception.RegraNegocioException caso o plano de medição 
     * informado não possua nome para a verificação ou já exista um PlanoMedicao com o mesmo nome no banco de dados.
     */
    public void validarVOUnico(PlanoMedicaoVO planoMedicao) throws Exception, NegocioException {
        
        if(planoMedicao.getNoPlanoMedicao() == null || planoMedicao.getNoPlanoMedicao().isEmpty())
            throw new Exception("Nome do plano de medição não foi informado");
        
        PlanoMedicaoVO planoMedicaoExemplo = new PlanoMedicaoVO();
        planoMedicaoExemplo.setNoPlanoMedicao(planoMedicao.getNoPlanoMedicao());
        
        if(!planoMedicaoDAO.consultarPorExemplo(planoMedicaoExemplo).isEmpty())
            throw new NegocioException("Já existe um plano de medição de nome " + planoMedicao.getNoPlanoMedicao() +
                " na base de dados");
    }
    
    /**
     * Verifica se o plano de medição está associado a objetivos. Se positivo,
     * o plano não pode ser excluído.
     * 
     * @param planoMedicao plano de medição a ser verificado.
     * @throws br.uniceub.fsw.arquitetura.servico.exception.RegraNegocioException caso o plano 
     * esteja associado a objetivos
     */
    public void validaExclusão(PlanoMedicaoVO planoMedicao) throws Exception, NegocioException {
    
        if(planoMedicao.getIdPlanoMedicao() == null)
            throw new Exception("Plano de medição não foi informado");
        
        if (planoMedicao.getStPlanoMedicaoVigente() != null && planoMedicao.getStPlanoMedicaoVigente().equals("S"))
            throw new NegocioException("O plano de medição vigente não pode ser excluído");
        
/*        PlanoMedicaoObjetivoVO planoMedicaoObjetivoExemplo = new PlanoMedicaoObjetivoVO();
        planoMedicaoObjetivoExemplo.setCdObjetivo(planoMedicao.getIdPlanoMedicao());
        
        List<PlanoMedicaoObjetivoVO> po = new PlanoMedicaoObjetivoDAO().consultarPorExemplo(planoMedicaoObjetivoExemplo);
                
        if(po.size() > 0 ) 
             throw new NegocioException("O plano de medição não pode ser excluído " +
                     "pois está associado a um objetivo");
  */      
    }
    
    public void validaAlteracao(PlanoMedicaoVO planoMedicao) throws Exception, NegocioException {
    
        if(planoMedicao.getIdPlanoMedicao() == null)
            throw new NegocioException("O plano de medição não foi informado");
        
        if (planoMedicao.getStPlanoMedicaoAprovado().equals("S"))
            throw new NegocioException("O plano de medição não pode ser alterado " +
                     "pois está aprovado.");          
    }
    
    /**
     * Aprova o plano de medição indicado. 
     * 
     * @param planoMedicao plano a ser aprovado
     */
    public void aprovaPlanoMedicao(PlanoMedicaoVO planoMedicao) throws Exception, NegocioException {
       
        if(planoMedicao.getIdPlanoMedicao() == null)
            throw new NegocioException("O plano de medição não foi informado");
        
        planoMedicao = planoMedicaoDAO.consultarPorId(planoMedicao.getIdPlanoMedicao());
        
        if(planoMedicao == null)
            throw new NegocioException("O plano de medição não foi informado");
        
        PlanoMedicaoVO vigente = planoMedicaoDAO.consultarPlanoVigente();

        if(!planoMedicao.getStPlanoMedicaoVigente().equals("S")) {
            
            if(planoMedicao.getStPlanoMedicaoAprovado().equals("S"))
                throw new NegocioException("O plano de medição já foi aprovado.");
            
            if(planoMedicao.getDtValidade().compareTo(new Date()) == -1) 
                throw new NegocioException("A data de validade do plano de medição está vencida.");            
            
            try {
                Transacao.iniciar();
            
                if(vigente != null) {
                    vigente.setDtValidade(new Date());
                    vigente.setStPlanoMedicaoVigente("N");
                    planoMedicaoDAO.alterar(vigente);
                }
                
                planoMedicao.setStPlanoMedicaoAprovado("S");
                planoMedicao.setStPlanoMedicaoVigente("S");
                planoMedicaoDAO.alterar(planoMedicao);
                
                Transacao.efetivar();
            }
            catch(Exception e) {
                Transacao.desfazer();
                throw new Exception(e.getMessage());
            }
        }       
    }
}
